package com.smh.multipeType;

/**
 * @description: 多态测试
 * @author: shenmhk
 * @create: 2020-10-23 15:04
 */
public class DuotaiTest {
    public static void main(String[] args) {

        A a1 = new A();
        A a2 = new A();
        B b = new B();
        C c = new C();
        D d = new D();
        //show(A obj) 应该传A类型的，但传入是B类型，又因为B是A的子类，B向上转型成A类型
        System.out.println(a1.show(b));//A and A     B向上转型A
        System.out.println(a1.show(c));//A and A     C向上转型A
        System.out.println(a1.show(d));//A and D    调用show(D obj)方法
        System.out.println();

        /**
         * 以下是分析：
         */
        /*
         * A a2 = new B(); 这里a2的引用类型是A，但是它指向的内存是类型为B的一个实例
         * 想对a2进行方法调用，
         * 你调用的方法都必须在class A里面有的才行 （因为你的引用类型为A）
         * 这里 class A有 show(A obj) show(D obj)着两个方法
         * a2.show(b) 在class A中没有找到类型匹配的方法，
         * 但是对b进行向上转型后， 可以找到 show(A obj)方法
         * 但是a2内存地址指向一个类型为B内存空间
         * 如果class B Override 了 class A的show(A  obj)方法，则调用B的show(A obj)方法
         */
        // class A中没有show(b)这个方法，但是由于B是A的子类，可以进行向上转型为A，可以找到show(A obj)方法，但是a2内存地址指向一个类型为B内存空间，并且classB 重写了class A的show(A obj)方法，则调用B的show(A obj)方法
        System.out.println(a2.show(b));
        // class A中没有show(c)这个方法，但是由于C是B的之类，B是A的之类，可以进行向上转型为A，可以找到show(A obj)方法，但是a2内存地址指向一个类型为B内存空间，并且classB 重写了class A的show(A obj)方法，则调用B的show(A obj)方法
        System.out.println(a2.show(c));
        // class A中没有show(c)这个方法，但是由于D是B的之类，B是A的之类，可以进行向上转型为A，可以找到show(A obj)方法，但是a2内存地址指向一个类型为B内存空间，并且classB 重写了class A的show(A obj)方法，则调用B的show(A obj)方法
        System.out.println(a2.show(d));
        System.out.println();

        //直接调用B的show(B obj)方法
        System.out.println(b.show(b));
        //C向上转型为B，调用B的show(B obj)方法
        System.out.println(b.show(c));
        //java中这里精准匹配到A的show(D obj)方法，因为A是B的父类；但是在C#中则不会调用B的父类中的方法，因为
        //B b = new B();和A没有关系
        System.out.println(b.show(d));
    }
}
